﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Web;
using System.Web.Caching;
using System.Xml;

namespace MyGroups.Model
{

    public class GroupReader : BaseXmlReader, IGroupReader
    {

        public Group GetGroup(string feedUrl)
        {
            Cache cache = HttpRuntime.Cache;
            string cacheKey = "GetGroup-" + feedUrl;
            if (Configuration.CachingEnabled)
            {
                if (cache[cacheKey] != null)
                {
                    return cache[cacheKey] as Group;
                }
            }

            Group group = null;

            try
            {
                var request = WebRequest.Create(feedUrl);
                var response = request.GetResponse();
                var stream = response.GetResponseStream();
                var reader = XmlReader.Create(stream);
                XmlDocument document = new XmlDocument();
                document.Load(reader);

                /* Sample format:
                   <group version="1.0" uid="http://group.com/">
                    <name>Group Name</name>
                    <websiteUrl>http://group.com/</websiteUrl>
                    <logoUrl>http://group.com/logo.png</logoUrl>
                    <description><![CDATA[<p>The description in CDATA to allow HTML.</p>]]></description>
                    <location latitude="" longitude="" />
                    <tags>
                        <tag>technology</tag>
                        <tag>iphone</tag>
                    </tags>
                    <icsUrl>http://group.com/calendar.ics</icsUrl>
                    <rssUrl>http://group.com/blog.rss</rssUrl>
                    <servicesUrl>http://group.com/services/</services>
                   </group>
                 */

                XmlNode rootNode = document.SelectSingleNode("/group");
                if (rootNode != null)
                {
                    group = new Group()
                    {
                        Version = GetNodeAttributeText(rootNode, "@version"),
                        UID = GetNodeAttributeText(rootNode, "@uid"),
                        Name = GetNodeInnerText(rootNode, "name"),
                        WebsiteUrl = GetNodeInnerText(rootNode, "websiteUrl"),
                        LogoUrl = GetNodeInnerText(rootNode, "logoUrl"),
                        Description = GetNodeInnerText(rootNode, "description"),
                        LocationLatitude = GetNodeAttributeText(rootNode, "location/@latitude"),
                        LocationLongitude = GetNodeAttributeText(rootNode, "location/@longitude"),
                        Tags = new List<string>(),
                        IcsUrl = GetNodeInnerText(rootNode, "icsUrl"),
                        RssUrl = GetNodeInnerText(rootNode, "rssUrl"),
                        ServicesUrl = GetNodeInnerText(rootNode, "servicesUrl"),
                    };
                    foreach (XmlNode tagNode in rootNode.SelectNodes("tags/tag"))
                    {
                        var tag = GetNodeInnerText(tagNode);
                        if (!String.IsNullOrEmpty(tag))
                        {
                            group.Tags.Add(tag);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // do nothing
                throw ex;
            }

            if (Configuration.CachingEnabled)
            {
                // hold up to 5 minutes
                cache.Insert(cacheKey, group, null, DateTime.Now.AddMinutes(5),
                    Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
            }

            return group;
        }

        public GroupCollection GetGroups(string feedUrl)
        {
            Cache cache = HttpRuntime.Cache;
            string cacheKey = "GetGroups-" + feedUrl;
            if (Configuration.CachingEnabled)
            {
                if (cache[cacheKey] != null)
                {
                    return cache[cacheKey] as GroupCollection;
                }
            }

            var collection = new GroupCollection();
            var urlList = new List<string>();

            try
            {
                var request = WebRequest.Create(feedUrl);
                var response = request.GetResponse();
                var stream = response.GetResponseStream();
                var reader = XmlReader.Create(stream);
                XmlDocument document = new XmlDocument();
                document.Load(reader);

                /*
                <?xml version="1.0" encoding="UTF-8"?>
                <opml version="1.1">
	                <head>
		                <title>My Groups</title>
		                <dateCreated>Fri, 16 Oct 2009 11:59:58 GMT</dateCreated>
		                <dateModified>Fri, 16 Oct 2009 11:59:58 GMT</dateModified>
		                <ownerName>Brennan Stehling</ownerName>
		                <ownerEmail>brennan@smallsharptools.com</ownerEmail>
	                </head>
	                <body>
		                <outline text="Web414" xmlUrl="http://www.theresgonnabesnacks.com/data/group.xml"/>
		                <outline text="Spreenkler" xmlUrl="http://www.theresgonnabesnacks.com/data/group2.xml"/>
		                <outline text="MIMA" xmlUrl="http://www.theresgonnabesnacks.com/data/group3.xml"/>
	                </body>
                </opml>
                 * */
                XmlNode rootNode = document.SelectSingleNode("/opml");
                if (rootNode != null)
                {
                    foreach (XmlNode outlineNode in rootNode.SelectNodes("//body/outline"))
                    {
                        var url = GetNodeAttributeText(outlineNode, "@xmlUrl");
                        if (!String.IsNullOrEmpty(url))
                        {
                            urlList.Add(url);
                        }
                    }
                }

                foreach (var url in urlList)
                {
                    var group = GetGroup(url);
                    if (collection != null)
                    {
                        collection.Add(group);
                    }
                }
            }
            catch (Exception ex)
            {
                // do nothing
                throw ex;
            }

            if (Configuration.CachingEnabled)
            {
                // hold up to 5 minutes
                cache.Insert(cacheKey, collection, null, DateTime.Now.AddMinutes(5),
                    Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
            }

            return collection;
        }

    }

}
